/**
 * @(#)DateUtils.java 2009-8-5
 * 
 *                    Copyright (C) 2009 PNK, Inc. All rights reserved.
 */

package com.gome.utils;

import org.apache.commons.lang3.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * 日期处理工具类，用于按指定的格式转换日期.
 * 
 * @author fasoal
 */
public final class DateUtils {
	/**
	 * 日期格式字符串yyyy-MM-dd HH:mm:ss.
	 */
	public static final String YYYY_MM_DDDD_HH24_MI_SS = "yyyy-MM-dd HH:mm:ss";

	/**
	 * 日期格式字符串yyyy-MM-dd HH:mm:ss.SSS
	 */
	public static final String YYYY_MM_DDDD_HH24_MI_SS_S = "yyyy-MM-dd HH:mm:ss.SSS";

	/**
	 * 日期格式字符串yyyy-MM-dd HH:mm:ss.
	 */
	public static final String YYYY_MM_DDDD_HH24_MI = "yyyy-MM-dd HH:mm";

	/**
	 * 日期格式字符串MM-dd HH:mm.
	 */
	public static final String MM_DDDD_HH24_MI = "MM-dd HH:mm";

	/**
	 * 日期格式字符串yyyy-MM-dd.
	 */
	public static final String YYYY_MM_DDDD = "yyyy-MM-dd";
	/**
	 * 日期格式字符串yyyy年MM月dd日.
	 */
	public static final String YYYY_MM_DDDD_CN = "yyyy年MM月dd日";
	/**
	 * 日期格式字符串yyyy年MM月dd日.
	 */
	public static final String YYYY_M_D_CN = "yyyy年M月d日";

	/** 日期格式字符串yyyy-MM */
	public static final String YYYY_MM = "yyyy-MM";

	/** 日期格式字符串yyyyMM */
	public static final String YYYYMM = "yyyyMM";

	/** 日期格式字符串yyMM */
	public static final String YYMM = "yyMM";

	/**
	 * 日期格式字符串yyyyMMdd.
	 */
	public static final String YYYYMMDD = "yyyyMMdd";
	/**
	 * 日期格式字符串yyMMdd.
	 */
	public static final String YYMMDD = "yyMMdd";

	/**
	 * 一天都多少毫秒.
	 */
	private static final int DAY_MILLISECOND = 86400000;
	/**
	 * 一天都多少毫秒.
	 */
	private static final int HOUR_MILLISECOND = 3600000;

	/**
	 * 默认构造函数，防止工具类被实例化.
	 */
	private DateUtils() {

	}

	/**
	 * 将指定的字符串转换成日期格式.
	 * 
	 * @param strDate 要转换的日期类型的字符串数据
	 * @param pattern 日期格式
	 * @return 转换后的日期
	 */
	public static Date parseDate(String strDate, String pattern) {
		// 要转换的字符串为空时，返回一个空的日期对象.
		if (StringUtils.isEmpty(strDate)) {
			return null;
		}

		SimpleDateFormat format = new SimpleDateFormat(pattern);
		try {
			return format.parse(strDate);
		}
		catch (ParseException e) {
			e.printStackTrace();
			throw new RuntimeException("非法的日期格式字符串:" + strDate);
		}
	}

	/**
	 * 按指定的格式将日期转换成字符串.
	 * 
	 * @param date 要转换的日期
	 * @param pattern 日期格式
	 * @return 转换后的日期字符串
	 */
	public static String formatDate(Date date, String pattern) {
		// 加入空日期返回.
		if (date == null) {
			return "";
		}

		SimpleDateFormat format = new SimpleDateFormat(pattern);
		return format.format(date);
	}

	/**
	 * 获得当前年份.
	 * 
	 * @return 当前年份，格式如：2003
	 */
	public static int getCurrentYear() {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
		// 格式化获取年，返回整形.
		return Integer.parseInt(sdf.format(new Date()));
	}

	/**
	 * 获得当前月份.
	 *
	 * @return 当前月份.
	 */
	public static int getCurrentMonth() {
		SimpleDateFormat sdf = new SimpleDateFormat("M");
		// 格式化获取当前月，返回整形.
		return Integer.parseInt(sdf.format(new Date()));
	}

	/**
	 * 获得当前天.
	 *
	 * @return 当前天.
	 */
	public static int getCurrentDay() {
		Calendar calendar = Calendar.getInstance();
		return calendar.get(Calendar.DATE);
	}

	/**
	 * 判断两个日期是否相等.
	 *
	 * @param dateOne 日期一.
	 * @param dateTwo 日期二.
	 * @param day 天数.
	 * @return 是否相等.
	 */
	public static boolean compareDate(String dateOne, String dateTwo, String day) {
		Calendar c = null;
		int i = 0;
		try {
			c = Calendar.getInstance();
			SimpleDateFormat sdf = new SimpleDateFormat(YYYY_MM_DDDD);
			// 格式化两个日期
			Date date1 = sdf.parse(dateOne);
			Date date2 = sdf.parse(dateTwo);
			c.setTime(date1);
			c.add(1, Integer.parseInt(day));

			date1 = c.getTime();
			// 比较两个时间
			i = date2.compareTo(date1);
		}
		catch (ParseException ex) {
			ex.printStackTrace();
		}
		// 0 表示为空
		if (i >= 0) {
			return true;
		}
		return false;
	}

	/**
	 * 返回两个日期相差天数.
	 * 
	 * @param d1 日期
	 * @param d2 日期
	 * @return 天数
	 */
	public static int diffDate(Date d1, Date d2) {
		// 如果两个日期都为空，则返回.
		if ((d1 == null) || (d2 == null)) {
			// 0表示返回值为空
			return 0;
		}

		Calendar cal = Calendar.getInstance();
		// from Locale, has nothing to do with your input date format
		int zoneoffset = cal.get(Calendar.ZONE_OFFSET);
		int dstoffset = cal.get(Calendar.DST_OFFSET);

		// getTime() return absolute GMT time
		// compensate with the offsets
		long dl1 = d1.getTime() + zoneoffset + dstoffset;
		long dl2 = d2.getTime() + zoneoffset + dstoffset;

		int intDaysFirst = (int) (dl1 / DAY_MILLISECOND); // 60 * 60 * 1000 *
		// 24
		int intDaysSecond = (int) (dl2 / DAY_MILLISECOND);
		// 设置一个临时返回值为 0.
		int tmpValue = 0;
		if (intDaysFirst > intDaysSecond) {
			// 如果第一个日期大于第二个日期，则用第一个日期减去第二个日期得到相差天数.
			tmpValue = intDaysFirst - intDaysSecond;
		} else {
			// 相反 ,如果第二个日期大于第一个日期，则用第二个日期减去第一个日期得到相差天数.
			tmpValue = intDaysSecond - intDaysFirst;
		}
		return tmpValue;
	}

	/**
	 * 返回两个日期相差天数.
	 * 
	 * @param d1 日期
	 * @param d2 日期
	 * @return 天数
	 */
	public static int diffHour(Date d1, Date d2) {
		// 如果两个日期都为空，则返回.
		if ((d1 == null) || (d2 == null)) {
			// 0表示返回值为空
			return 0;
		}

		Calendar cal = Calendar.getInstance();
		// from Locale, has nothing to do with your input date format
		int zoneoffset = cal.get(Calendar.ZONE_OFFSET);
		int dstoffset = cal.get(Calendar.DST_OFFSET);

		// getTime() return absolute GMT time
		// compensate with the offsets
		long dl1 = d1.getTime() + zoneoffset + dstoffset;
		long dl2 = d2.getTime() + zoneoffset + dstoffset;

		int intDaysFirst = (int) (dl1 / HOUR_MILLISECOND); // 60 * 60 * 1000
		int intDaysSecond = (int) (dl2 / HOUR_MILLISECOND);
		// 设置一个临时返回值为 0.
		int tmpValue = 0;
		if (intDaysFirst > intDaysSecond) {
			// 如果第一个日期大于第二个日期，则用第一个日期减去第二个日期得到相差天数.
			tmpValue = intDaysFirst - intDaysSecond;
		} else {
			// 相反 ,如果第二个日期大于第一个日期，则用第二个日期减去第一个日期得到相差天数.
			tmpValue = intDaysSecond - intDaysFirst;
		}
		return tmpValue;
	}

}
